package cn.zhqr.lib.utils;

import cn.zhqr.lib.bean.response.ErrorCode;
import cn.zhqr.lib.config.GlobalConfig;
import cn.zhqr.lib.config.Global;
import cn.zhqr.lib.exception.ErrorCodeException;
import cn.zhqr.lib.external.aliyun.SmsSender;
import cn.zhqr.common.util.digest.MD5Utils;
import cn.zhqr.common.util.number.NumberUtils;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.redis.Redis;
import com.jfinal.render.RenderException;
import org.apache.log4j.Logger;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class MobileVerifyCodeKit {
    private static final Logger log = Logger.getLogger(MobileVerifyCodeKit.class);

    // 默认的验证码大小
    private static final int WIDTH = 108, HEIGHT = 40;

    public static void renderImgCode(Long userid, HttpServletResponse resp){
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

        String captcha = CaptchaKit.gene(image);
        log.info(userid+"生成验证码："+captcha);

        captcha = captcha.toUpperCase();
        captcha = HashKit.md5(captcha);

        if(StrKit.notBlank(captcha)){
            if(GlobalConfig.serverMode == Global.SERVER_MODE_PRO){
                Redis.use().setex(Global.mobile_verify_code.img_code+userid,30*60,captcha);
            }
        }

        ServletOutputStream sos = null;
        try {
            sos = resp.getOutputStream();
            ImageIO.write(image, "jpeg", sos);
        } catch (Exception e) {
            throw new RenderException(e);
        } finally {
            if (sos != null) {
                try {sos.close();} catch (IOException e) {
                    LogKit.logNothing(e);}
            }
        }
    }

    public static void send(String mobile,Object sid){
        if(GlobalConfig.serverMode == Global.SERVER_MODE_PRO){
            String verify_code = Redis.use().get(Global.mobile_verify_code.agent_auth+sid);
            if(StrKit.notBlank(verify_code)){
                throw new ErrorCodeException(ErrorCode.OPERATE_TOO_FREQUENT.code,"您的操作过于频繁，请稍后再试");
            }
            verify_code = Redis.use().get(Global.mobile_verify_code.agent_auth + mobile);
            if(StrKit.notBlank(verify_code)){
                throw new ErrorCodeException(ErrorCode.OPERATE_TOO_FREQUENT.code,"该手机号操作过于频繁，请稍后再试");
            }

            try {
                verify_code = NumberUtils.random(4);
                SmsSender.sendCode(mobile,verify_code);

                log.info(mobile+"生成验证码："+verify_code);

                Redis.use().setex(Global.mobile_verify_code.agent_auth+mobile,60,System.currentTimeMillis());
                if(sid!=null){
                    Redis.use().setex(Global.mobile_verify_code.agent_auth+sid,60,System.currentTimeMillis());
                }
                //短信验证码10分钟内有效
                Redis.use().setex(Global.mobile_verify_code.mobile_verify_code+mobile,10*60,verify_code);
            } catch (Exception e) {
                log.error(e);
                throw new ErrorCodeException(ErrorCode.NETWORK_ERROR.code,"短信发送失败，请联系管理员");
            }
        }
    }

    public static boolean valid(String mobile,String verify_code){
        return valid(mobile, verify_code,false);
    }

    public static boolean valid(String mobile,String verify_code,boolean need_md5){
        if(StrKit.isBlank(verify_code)){
            return false;
        }
        String last_verify_code = "1234";
        if(GlobalConfig.serverMode == Global.SERVER_MODE_PRO || GlobalConfig.serverMode == Global.SERVER_MODE_PRE_PRO){
            last_verify_code = Redis.use().get(Global.mobile_verify_code.mobile_verify_code + mobile);

            if(StrKit.isBlank(last_verify_code)){
                return false;
            }
        }
        if(need_md5){
            last_verify_code = MD5Utils.md5(last_verify_code);
        }

        return verify_code.equals(last_verify_code);
    }
}
